;> Array Operations
LETARRAY LDRB R10,[AELINE],#1
 CMP R10,#" "
 BEQ LETARRAY
 CMP R10,#"-"
 BEQ ARRAYNEGATE
 STMFD SP!,{AELINE}
 RSBS R0,R10,#"9"
 CMPCS R10,#"."
 BCS ARRAYFACT
 BL LVCONT
 BEQ ARRAYFACT
 ADD SP,SP,#4
 CMP TYPE,#256
 BCC ARRAYFACTLV
 BL AESPAC
 CMP R10,#"+"
 CMPNE R10,#"-"
 CMPNE R10,#"*"
 CMPNE R10,#"/"
 CMPNE R10,#"."
 BEQ ARRAYBINARY
 BL AEDONE
 LDMFD SP!,{R4,R5} ;copy an array to another one
 CMP TYPE,R5
 BNE ERTYPEARRAYB
 LDR R6,[IACC]
 LDR R4,[R4]
 CMP R6,#16
 CMPCS R4,#16
 BCC ERARRZ
ARRAYARRAYASSIGNSIZE LDR R5,[R4],#4
 LDR R7,[R6],#4
 CMP R5,R7
 BNE ERTYPEARRAYC
 CMP R5,#0
 BNE ARRAYARRAYASSIGNSIZE
 LDR AELINE,[R4],#4 ;total number of elements
 ADD R6,R6,#4
 SUB TYPE,TYPE,#256
 CMP TYPE,#TFPLV
 BHI ARRAYARRAYASSIGNSTRING
 [ FP=0
 ADDEQ AELINE,AELINE,AELINE,LSL #2
 ADDEQ AELINE,AELINE,#3
 BICEQ AELINE,AELINE,#3
 |
 MOVEQ AELINE,AELINE,LSL #3
 ]
 MOVNE AELINE,AELINE,LSL #2 ;calculate number of bytes to copy
ARRAYARRAYASSIGNCOPY SUBS AELINE,AELINE,#16
 LDMHSIA R6!,{R0,R1,R2,R3}
 STMHSIA R4!,{R0,R1,R2,R3}
 BHI ARRAYARRAYASSIGNCOPY
 BEQ NXT
 CMN AELINE,#8
 LDMLOIA R6!,{R0}
 STMLOIA R4!,{R0}
 LDMEQIA R6!,{R0,R1}
 STMEQIA R4!,{R0,R1}
 LDMHIIA R6!,{R0,R2,R3}
 STMHIIA R4!,{R0,R2,R3}
 B NXT
ARRAYARRAYASSIGNSTRING MOV TYPE,R6 ;source
ARRAYARRAYASSIGNSTRING1 LOAD R3,TYPE,R6,R7
 LDRB R2,[TYPE,#4]
 ADD TYPE,TYPE,#5
 ADD R2,R2,R3
 BL STSTORE
 ADD R4,R4,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYARRAYASSIGNSTRING1
 B NXT
ARRAYBINARY STMFD SP!,{IACC,TYPE,R10}
 STMFD SP!,{AELINE}
 BL AESPAC
 RSBS R0,R10,#"9"
 CMPCS R10,#"."
 BCS ARRAYBINARYCONST
 BL LVCONT
 BEQ ARRAYBINARYCONST
 ADD SP,SP,#4
 BL AEDONES
 CMP TYPE,#256
 BCC ARRAYBINARYCONSTLV
 LDMFD SP!,{R1,R2,R3,R4,R5} ;R1,2=LV1,TYPE; R3=OP; R4,5=LV0,TYPE
 CMP TYPE,R2
 CMPEQ R2,R5
 BNE ERTYPEARRAYB
 LDR IACC,[IACC]
 LDR R1,[R1]
 LDR R4,[R4]
 CMP IACC,#16
 CMPCS R1,#16
 CMPCS R4,#16
 BCC ERARRZ ;if any array undimensioned
 CMP R3,#"."
 BEQ MATRIXMULTIPLY
ARRAYBINARYSIZE LDR R2,[IACC],#4
 LDR R5,[R1],#4
 LDR R6,[R4],#4
 CMP R2,R5
 CMPEQ R5,R6
 BNE ERTYPEARRAYC
 CMP R6,#0
 BNE ARRAYBINARYSIZE
 LDR AELINE,[R4],#4 ;number of items
 ADD IACC,IACC,#4
 ADD R1,R1,#4
 SUB TYPE,TYPE,#256
 CMP R3,#"-"
 BEQ ARRAYBINARYSUB
 CMP R3,#"*"
 BEQ ARRAYBINARYMUL
 CMP R3,#"/"
 BEQ ARRAYBINARYDIV
 CMP TYPE,#TFPLV
 BEQ ARRAYBINARYADDFP
 BCS ARRAYBINARYADDSTRING
ARRAYBINARYADDINT LDR R2,[IACC],#4
 LDR R3,[R1],#4
 ADD R2,R2,R3
 STR R2,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYADDINT
 B NXT
ARRAYBINARYADDFP
 [ FP=0
 STMFD SP!,{R8,R10} ;save pointers
 MOV R10,R4
 MOV R8,R1
 MOV TYPE,R0
ARRAYBINARYADDFP1 BL F1LDA
 ADD R7,TYPE,#5
 MOV TYPE,R8
 MOV R8,R7
 BL F1ADD
 ADD TYPE,TYPE,#5
 MOV R4,R10
 BL F1STABYR4
 ADD R10,R10,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYADDFP1
 LDMFD SP!,{R8,R10}
 |
 LDFD FACC,[IACC],#8
 LDFD F1,[R1],#8
 ADFD FACC,FACC,F1
 STFD FACC,[R4],#8
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYADDFP
 ]
 B NXT
ARRAYBINARYADDSTRING STMFD SP!,{R0,R10}
 MOV R10,R1
ARRAYBINARYADDSTRING1 MOV IACC,R10
 BL VARSTR
 ADD R10,R10,#5
 LDR IACC,[SP]
 ADD R1,IACC,#5
 STR R1,[SP]
 LDRB R5,[IACC,#4]
 TEQ R5,#0
 BEQ ARRAYBINARYADDSTRING3
 LOAD IACC,IACC,R1,R3
 ADD R6,CLEN,R5
 ADD R1,ARGP,#STRACC+256
 CMP R6,R1
 BCS ERLONG
ARRAYADDBINARYSTRING2 LDRB R1,[IACC],#1
 STRB R1,[CLEN],#1
 SUBS R5,R5,#1
 BNE ARRAYADDBINARYSTRING2
ARRAYBINARYADDSTRING3 ADD R3,ARGP,#STRACC
 BL STSTORE
 ADD R4,R4,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYADDSTRING1
 LDMFD SP!,{R0,R10}
 B NXT 
ARRAYBINARYSUB CMP TYPE,#TFPLV
 BEQ ARRAYBINARYSUBFP
 BCS ERTYPEARRAYB
ARRAYBINARYSUBINT LDR R2,[IACC],#4
 LDR R3,[R1],#4
 SUB R2,R3,R2
 STR R2,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYSUBINT
 B NXT
ARRAYBINARYSUBFP
 [ FP=0
 STMFD SP!,{R8,R10} ;save pointers
 MOV R10,R4
 MOV R8,R1
 MOV TYPE,R0
ARRAYBINARYSUBFP1 BL F1LDA
 ADD R4,TYPE,#5
 MOV TYPE,R8
 MOV R8,R4
 BL F1XSUB
 ADD R4,TYPE,#5
 MOV TYPE,R10
 BL F1STA
 MOV TYPE,R8
 MOV R8,R4
 ADD R10,R10,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYSUBFP1
 LDMFD SP!,{R8,R10}
 |
 LDFD FACC,[IACC],#8
 LDFD F1,[R1],#8
 SUFD FACC,F1,FACC
 STFD FACC,[R4],#8
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYSUBFP
 ]
 B NXT
ARRAYBINARYMUL CMP TYPE,#TFPLV
 BEQ ARRAYBINARYMULFP
 BCS ERTYPEARRAYB
ARRAYBINARYMULINT LDR R2,[IACC],#4
 LDR R3,[R1],#4
 MUL R2,R3,R2
 STR R2,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYMULINT
 B NXT
ARRAYBINARYMULFP
 [ FP=0
 STMFD SP!,{R8,R10} ;save pointers
 MOV R10,R4
 MOV R8,R1
 MOV TYPE,R0
ARRAYBINARYMULFP1 BL F1LDA
 ADD R7,TYPE,#5
 MOV TYPE,R8
 MOV R8,R7
 BL F1MUL
 ADD TYPE,TYPE,#5
 MOV R4,R10
 BL F1STABYR4
 ADD R10,R10,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYMULFP1
 LDMFD SP!,{R8,R10}
 |
 LDFD FACC,[IACC],#8
 LDFD F1,[R1],#8
 MUFD FACC,F1,FACC
 STFD FACC,[R4],#8
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYMULFP
 ]
 B NXT
ARRAYBINARYDIV CMP TYPE,#TFPLV
 BEQ ARRAYBINARYDIVFP
 BCS ERTYPEARRAYB
ARRAYBINARYDIVINT LDR R3,[IACC],#4
 LDR R2,[R1],#4
 BL ARRAYINTDIV
 STR TYPE,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYDIVINT
 B NXT
ARRAYBINARYDIVFP
 [ FP=0
 STMFD SP!,{R8,R10} ;save pointers
 MOV R10,R4
 MOV R8,R1
 MOV TYPE,R0
ARRAYBINARYDIVFP1 BL F1LDA
 ADD R4,TYPE,#5
 MOV TYPE,R8
 MOV R8,R4
 BL F1XDIV
 ADD R4,TYPE,#5
 MOV TYPE,R10
 BL F1STA
 MOV TYPE,R8
 MOV R8,R4
 ADD R10,R10,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYDIVFP1
 LDMFD SP!,{R8,R10}
 |
 LDFD FACC,[IACC],#8
 LDFD F1,[R1],#8
 DVFD FACC,F1,FACC
 STFD FACC,[R4],#8
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYDIVFP
 ]
 B NXT
ARRAYPLUSBC MOV R6,#"+"
 MOV R7,R4
 MOV AELINE,R5
 B ARRAYBINARYCONST1
ARRAYBINARYCONSTLV BL VARIND
 B ARRAYBINARYCONSTRV
ARRAYBINARYCONST LDMFD SP!,{AELINE}
 BL FACTOR
 BL AEDONES
;A()         =B()     op   C%
;sp+12,sp+16 =sp,sp+4 sp+8 in acc
ARRAYBINARYCONSTRV LDMFD SP!,{R4,R5,R6,R7,AELINE}
 CMP R6,#"-"
 BNE ARRAYBINARYCONST1
 TEQ TYPE,#0
 BEQ ERTYPEARRAYB
 RSBPL IACC,IACC,#0
 [ FP=0
 EORMI FSIGN,FSIGN,#&80000000
 TEQ FACC,#0
 MOVEQ FSIGN,#0
 |
 RSFMID FACC,FACC,#0
 ]
 MOV R6,#"+"
ARRAYBINARYCONST1 CMP R6,#"+"
 CMPEQ R5,#256+128
 BEQ ARRAYBINARYCONST2
 CMP TYPE,#0
 BEQ ERTYPEINT
 BL PUSHTYPE
 STMFD SP!,{TYPE}
 MOV IACC,R4
 MOV TYPE,R5
 MOV R4,R7
 MOV R5,AELINE
 MOV R7,R6
 SUB R1,TYPE,#256
 CMP R7,#"/"
 BNE ARRAYCONSTBINARY1
 CMP R5,TYPE
 BNE ERTYPEARRAYB
 LDR R6,[IACC]
 LDR R4,[R4]
 CMP R6,#16
 CMPCS R4,#16
 BCC ERARRZ
ARRAYBINARYCONSTDIV1 LDR R5,[R4],#4
 LDR R2,[R6],#4
 CMP R5,R2
 BNE ERTYPEARRAYC
 CMP R5,#0
 BNE ARRAYBINARYCONSTDIV1
 LDR AELINE,[R4],#4 ;total number of elements
 ADD R6,R6,#4
 CMP R1,#TFPLV
 BHI ERTYPEARRAY
 BEQ ARRAYBINARYCONSTDIVFP
 BL PULLTYPE
 BL INTEGY
ARRAYBINARYCONSTDIVINT LDR R2,[R6],#4
 MOV R3,R0
 BL ARRAYINTDIV
 STR TYPE,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYCONSTDIVINT
 B NXT
ARRAYBINARYCONSTDIVFP BL PULLTYPE
 BL FLOATY
 STMFD SP!,{R8,R10}
 MOV R10,R4 ;D
 MOV R8,R6 ;S
 [ FP=0
 BL FPUSH
 TEQ FACC,#0
 |
 CMF FACC,#0
 ]
 BEQ ZDIVOR
 [ FP=0
ARRAYBINARYCONSTDIVFP1 MOV TYPE,R8
 ADD R8,R8,#5
 BL F1LDA
 BEQ ARRAYBINARYCONSTDIVFP2
 BL FTOW
 FLDA SP
 BL FDIVA
ARRAYBINARYCONSTDIVFP2 MOV TYPE,R10
 BL F1STA
 ADD R10,R10,#5
 |
ARRAYBINARYCONSTDIVFP1 LDFD F1,[R8]
 DVFD F1,F1,FACC
 STFD F1,[R8],#8
 ]
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYCONSTDIVFP1
 LDMFD SP!,{R0,R1,R8,R10}
 B NXT
ARRAYBINARYCONST2 CMP R5,AELINE
 BNE ERTYPEARRAYB
 CMP TYPE,#0
 BNE ERTYPESTR
 LDR R6,[R4]
 BL SPUSH
 LDR R4,[R7]
 CMP R4,#16
 CMPCS R6,#16
 BCC ERARRZ
ARRAYBINARYCONSTSIZE LDR R5,[R4],#4
 LDR R2,[R6],#4
 CMP R5,R2
 BNE ERTYPEARRAYC
 CMP R5,#0
 BNE ARRAYBINARYCONSTSIZE
 LDR AELINE,[R4],#4 ;total number of elements
 ADD R6,R6,#4
 STMFD SP!,{R10} ;add constant string to string array
 MOV R10,R6
ARRAYBINARYCONSTADDSTRING1 MOV IACC,R10
 BL VARSTR
 ADD R3,ARGP,#STRACC
 LDR R5,[SP,#4]
 SUBS R1,R5,R3
 BEQ ARRAYBINARYCONSTADDSTRING3
 ADD R6,R1,CLEN
 ADD R5,ARGP,#STRACC+256
 CMP R6,R5
 BCS ERLONG
 ADD R6,SP,#8
ARRAYBINARYCONSTADDSTRING2 LDRB R5,[R6],#1
 STRB R5,[CLEN],#1
 SUBS R1,R1,#1
 BNE ARRAYBINARYCONSTADDSTRING2
ARRAYBINARYCONSTADDSTRING3 BL STSTORE
 ADD R4,R4,#5
 ADD R10,R10,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYBINARYCONSTADDSTRING1
 LDMFD SP!,{R10}
 BL SPULL
 B NXT
ARRAYNEGATE STMFD SP!,{AELINE}
 BL AESPAC
 RSBS R0,R10,#"9"
 CMPCS R10,#"."
 BCS ARRAYFACT
 BL LVCONT
 BEQ ARRAYFACT
 ADD SP,SP,#4
 SUBS R1,TYPE,#256
 BCS ARRAYZEROMINUS
 BL VARIND
 BEQ ERTYPEINT
 RSBPL IACC,IACC,#0 ;negate integer
 BPL ARRAYFACTRV
 [ FP=0
 TEQ FACC,#0
 EORNE FSIGN,FSIGN,#&80000000 ;negate floating point
 |
 RSFD FACC,FACC,#0
 ]
 B ARRAYFACTRV
ARRAYFACTLV BL VARIND
 B ARRAYFACTRV
ARRAYFACT LDMFD SP!,{AELINE}
 SUB AELINE,AELINE,#1
 BL FACTOR
ARRAYFACTRV BL AESPAC
 CMP R10,#"+"
 CMPNE R10,#"-"
 CMPNE R10,#"*"
 CMPNE R10,#"/"
 BEQ ARRAYCONSTBINARY
 LDMFD SP!,{R4,R5} ;assign constant to an array
 LDR R4,[R4]
 CMP R4,#16
 BCC ERARRZ
ARRAYCONSTASSIGN1 LDR R6,[R4],#4
 CMP R6,#0
 BNE ARRAYCONSTASSIGN1
 SUB R5,R5,#256
 CMP R10,#","
 BEQ ARRAYCONSTS
 BL AEDONE
 LDR AELINE,[R4],#4 ;aeline=number of elements, r4=base
 CMP R5,#TFPLV
 BHI ARRAYCONSTASSIGNSTRING
 BEQ ARRAYCONSTASSIGNFP
 BL INTEGY ;make sure of INT
 MOV R5,AELINE,LSL #2 ;number of bytes
 BL INITIALISERAM
 B NXT
ARRAYCONSTASSIGNFP BL FLOATY ;make sure of FP
 [ FP=0
 BIC FACC,FACC,#&80000000
 ORR FACC,FACC,FSIGN ;fsign only 0 or &80000000!
 ORR FACCX,FACCX,FACC,LSL #8
 MOV R2,FACC,LSR #24
 ORR R2,R2,FACCX,LSL #8
 MOV R3,FACC,LSR #16
 ORR R3,R3,FACCX,LSL #16
 MOV R5,FACC,LSR #8
 ORR R5,R5,FACCX,LSL #24
ARRAYCONSTASSIGNFP1 SUBS AELINE,AELINE,#4
 STMHSIA R4!,{FACC,FACCX,R2,R3,R5} ;write four values
 BHI ARRAYCONSTASSIGNFP1
 BEQ NXT ;zero left
 CMN AELINE,#2
 STMLOIA R4!,{FACC,FACCX} ;first one
 STMEQIA R4!,{FACC,FACCX,R2} ;first two
 STMHIIA R4!,{FACC,FACCX,R2,R3} ;first three
 |
 STFD FACC,[SP,#-8]!
 LDMFD SP,{R0,R1}
 LDMFD SP!,{R2,R3}
ARRAYCONSTASSIGNFP1 SUBS AELINE,AELINE,#2
 STMHSIA R4!,{R0,R1,R2,R3} ;write two values
 BHI ARRAYCONSTASSIGNFP1
 STMNEIA R4!,{R0,R1} ;last one
 ]
 B NXT
ARRAYCONSTASSIGNSTRING CMP TYPE,#0
 BNE ERTYPESTR
 ADD R3,ARGP,#STRACC
ARRAYCONSTASSIGNSTRING1 BL STSTORE
 ADD R4,R4,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTASSIGNSTRING1
 B NXT
;r4 pointer to destination array, r5 type
ARRAYCONSTS LDR R6,[R4],#4 ;number of elements max
ARRAYCONSTS1 SUBS R6,R6,#1
 BMI ERRSUB
 STMFD SP!,{R4,R5,R6}
 BL STOREA ;store current value
 BL EXPR ;get next one
 LDMFD SP!,{R4,R5,R6}
 CMP R5,#128
 ADDCC R4,R4,R5 ;add size if type 4, 5/8
 ADDCS R4,R4,#5 ;else if type 128 then size 5
 CMP R10,#","
 BEQ ARRAYCONSTS1
 BL AEDONE
 SUBS R6,R6,#1
 BMI ERRSUB
 BL STOREA
 B NXT
ARRAYZEROMINUS BL AEDONES
 MOV R2,#TINTEGER
 MOV R3,#0
 LDMFD SP!,{R4,R5}
 STMFD SP!,{R2,R3}
 MOV R7,#"-"
 B ARRAYCONSTBINARY1
ARRAYCONSTBINARY LDMFD SP!,{R6,R7}
 BL PUSHTYPE
 STMFD SP!,{TYPE}
 STMFD SP!,{R6,R7,R10}
 BL LVBLNK
 BEQ ERTYPEARRAY
 SUBS R1,TYPE,#256
 BCC ERTYPEARRAY
 BL AEDONES
 LDMFD SP!,{R4,R5,R7}
;A()      =B%              op C()
;facc,type=pushed on stack r7 r4,r5
ARRAYCONSTBINARY1 CMP R5,TYPE
 BNE ERTYPEARRAYB
 LDR R6,[IACC]
 LDR R4,[R4]
 CMP R6,#16
 CMPCS R4,#16
 BCC ERARRZ
ARRAYCONSTBINARYSIZE LDR R5,[R4],#4
 LDR R2,[R6],#4
 CMP R5,R2
 BNE ERTYPEARRAYC
 CMP R5,#0
 BNE ARRAYCONSTBINARYSIZE
 LDR AELINE,[R4],#4 ;total number of elements
 ADD R6,R6,#4
 CMP R7,#"-"
 BEQ ARRAYCONSTBINARYMINUS
 CMP R7,#"*"
 BEQ ARRAYCONSTBINARYMUL
 CMP R7,#"/"
 BEQ ARRAYCONSTBINARYDIV
 CMP R7,#"."
 BEQ ERTYPEARRAY
 CMP R1,#TFPLV
 BHI ARRAYCONSTBINARYADDSTRING
 BEQ ARRAYCONSTBINARYADDFP
 BL PULLTYPE
 BL INTEGY
ARRAYCONSTBINARYADDINT LDR R1,[R6],#4
 ADD R1,R1,R0
 STR R1,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYADDINT
 B NXT
ARRAYCONSTBINARYADDFP BL PULLTYPE
 BL FLOATY
 [ FP=0
 STMFD SP!,{R8,R10}
 MOV R10,R4 ;D
 MOV R8,R6 ;S
 BL FPUSH
ARRAYCONSTBINARYADDFP1 MOV TYPE,R8
 ADD R8,R8,#5
 BL F1LDA
 MOV TYPE,SP
 BL FADD
 MOV TYPE,R10
 ADD R10,R10,#5
 BL F1STA
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYADDFP1
 LDMFD SP!,{R0,R1,R8,R10}
 |
ARRAYCONSTBINARYADDFP1 LDFD F1,[R6],#8
 ADFD F1,F1,FACC
 STFD F1,[R4],#8
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYADDFP1
 ]
 B NXT
ARRAYCONSTBINARYADDSTRING BL PULLTYPE
 STMFD SP!,{CLEN,R10}
 ADD R3,ARGP,#STRACC
 MOV R10,R6
ARRAYCONSTBINARYADDSTRING1 LDR CLEN,[SP]
 LDRB R5,[R10,#4]
 TEQ R5,#0
 BEQ ARRAYCONSTBINARYADDSTRING3
 LOAD R0,R10,R6,R7
 ADD R6,CLEN,R5
 ADD R1,ARGP,#STRACC+256
 CMP R6,R1
 BCS ERLONG
ARRAYCONSTBINARYADDSTRING2 LDRB R1,[R0],#1
 STRB R1,[CLEN],#1
 SUBS R5,R5,#1
 BNE ARRAYCONSTBINARYADDSTRING2
ARRAYCONSTBINARYADDSTRING3 BL STSTORE
 ADD R4,R4,#5
 ADD R10,R10,#5
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYADDSTRING1
 LDMFD SP!,{CLEN,R10}
 B NXT
ARRAYCONSTBINARYMINUS CMP R1,#TFPLV
 BHI ERTYPEARRAY
 BEQ ARRAYCONSTBINARYMINUSFP
 BL PULLTYPE
 BL INTEGY
ARRAYCONSTBINARYMINUSINT LDR R1,[R6],#4
 SUB R1,R0,R1
 STR R1,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYMINUSINT
 B NXT
ARRAYCONSTBINARYMINUSFP BL PULLTYPE
 BL FLOATY
 [ FP=0
 STMFD SP!,{R8,R10}
 MOV R10,R4 ;D
 MOV R8,R6 ;S
 BL FPUSH
ARRAYCONSTBINARYMINUSFP1 MOV TYPE,R8
 ADD R8,R8,#5
 BL F1LDA
 MOV TYPE,SP
 BL FXSUB
 MOV TYPE,R10
 ADD R10,R10,#5
 BL F1STA
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYMINUSFP1
 LDMFD SP!,{R0,R1,R8,R10}
 |
ARRAYCONSTBINARYMINUSFP1 LDFD F1,[R6],#8
 SUFD F1,FACC,F1
 STFD F1,[R4],#8
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYMINUSFP1
 ]
 B NXT
ARRAYCONSTBINARYMUL CMP R1,#TFPLV
 BHI ERTYPEARRAY
 BEQ ARRAYCONSTBINARYMULFP
 BL PULLTYPE
 BL INTEGY
ARRAYCONSTBINARYMULINT LDR R1,[R6],#4
 MUL R1,R0,R1
 STR R1,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYMULINT
 B NXT
ARRAYCONSTBINARYMULFP BL PULLTYPE
 BL FLOATY
 [ FP=0
 STMFD SP!,{R8,R10}
 MOV R10,R4 ;D
 MOV R8,R6 ;S
 BL FPUSH
ARRAYCONSTBINARYMULFP1 MOV TYPE,R8
 ADD R8,R8,#5
 BL F1LDA
 MOV TYPE,SP
 BL FMUL
 MOV TYPE,R10
 ADD R10,R10,#5
 BL F1STA
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYMULFP1
 LDMFD SP!,{R0,R1,R8,R10}
 |
ARRAYCONSTBINARYMULFP1 LDFD F1,[R6],#8
 MUFD F1,FACC,F1
 STFD F1,[R4],#8
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYMULFP1
 ]
 B NXT
ARRAYCONSTBINARYDIV CMP R1,#TFPLV
 BHI ERTYPEARRAY
 BEQ ARRAYCONSTBINARYDIVFP
 BL PULLTYPE
 BL INTEGY
ARRAYCONSTBINARYDIVINT LDR R3,[R6],#4
 MOV R2,R0
 BL ARRAYINTDIV
 STR TYPE,[R4],#4
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYDIVINT
 B NXT
ARRAYCONSTBINARYDIVFP BL PULLTYPE
 BL FLOATY
 [ FP=0
 STMFD SP!,{R8,R10}
 MOV R10,R4 ;D
 MOV R8,R6 ;S
 BL FPUSH
ARRAYCONSTBINARYDIVFP1 MOV TYPE,R8
 ADD R8,R8,#5
 BL F1LDA
 MOV TYPE,SP
 BL FXDIV
 MOV TYPE,R10
 ADD R10,R10,#5
 BL F1STA
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYDIVFP1
 LDMFD SP!,{R0,R1,R8,R10}
 |
ARRAYCONSTBINARYDIVFP1 LDFD F1,[R6],#8
 DVFD F1,FACC,F1
 STFD F1,[R4],#8
 SUBS AELINE,AELINE,#1
 BNE ARRAYCONSTBINARYDIVFP1
 ]
 B NXT
; TYPE=R2 DIV R3. Uses r5,r7 also
ARRAYINTDIV EOR R5,R2,R3
 MOVS R2,R2
 RSBMI R2,R2,#0
 MOVS R3,R3
 BEQ ZDIVOR
 RSBMI R3,R3,#0
 MOV R7,R3
 CMP R7,R2,LSR #1
ARRAYINTDIV1 MOVLS R7,R7,LSL #1
 CMPLS R7,R2,LSR #1
 BLS ARRAYINTDIV1
 MOV TYPE,#0
ARRAYINTDIV2 CMP R2,R7
 SUBCS R2,R2,R7
 ADC TYPE,TYPE,TYPE
 MOV R7,R7,LSR #1
 CMP R7,R3
 BCS ARRAYINTDIV2
 TEQ R5,#0
 RSBMI TYPE,TYPE,#0
 MOV PC,R14
;A(LIMI,LIMK)=B(LIMI,LIMJ).C(LIMJ,LIMK)
;R0=[LVC], R1=[LVB], R4=[LVA], TYPE=TYPE!
MATRIXMULTIPLY SUB TYPE,TYPE,#256
 CMP TYPE,#128
 BCS ERTYPEARRAYB
 CMP R4,R1
 CMPNE R4,R0
 BNE MATRIXMULTIPLYNOCOPY
;as a kindness, copy the destination to free space if it is the same as either
;of the sources. Issue whacky error message if this is not possible.
 MOV R5,R4
 MOV R6,R4
MATRIXMULTIPLYDESTSIZE LDR R7,[R6],#4
 TEQ R7,#0
 BNE MATRIXMULTIPLYDESTSIZE
 LDR R7,[R6],#4
 CMP TYPE,#4
 MOVEQ R7,R7,LSL #2
 [ FP=0
 ADDNE R7,R7,R7,LSL #2 ;number of bytes to move
 |
 MOVNE R7,R7,LSL #3
 ]
 SUB R6,R6,R5
 ADD R7,R7,R6
 LDR R6,[ARGP,#FSA]
 ADD R2,R6,R7
 ADD R2,R2,#1024
 CMP R2,SP
 BCS ERMATMULSPACE
MATRIXMULTIPLYCOPY LDR R2,[R5],#4
 STR R2,[R6],#4
 SUBS R7,R7,#4
 BCS MATRIXMULTIPLYCOPY
;set any identical source pointers to the copy
 CMP R4,R1
 LDREQ R1,[ARGP,#FSA]
 CMP R4,R0
 LDREQ R0,[ARGP,#FSA]
MATRIXMULTIPLYNOCOPY STMFD SP!,{R8,R10} ;more temporary registers
 LDR R2,[R4],#4 ;ALIMI
 LDR R3,[R1],#4 ;BLIMI
 LDR R5,[R0],#4 ;CLIMJ
 LDR R6,[R4],#4 ;ALIMK
 LDR R7,[R1],#4 ;BLIMJ
 LDR R10,[R0],#4 ;CLIMK
 CMP R6,#0
 BEQ VECTORMULTIPLY
 CMP R2,R3 ;test LIMI
 CMPEQ R7,R5 ;test LIMJ
 CMPEQ R6,R10 ;test LIMK
 LDR R3,[R4],#8 ;load 0 and skip number of items
 CMPEQ R3,#0
 LDR R3,[R1],#8
 CMPEQ R3,#0
 LDR R3,[R0],#8
 CMPEQ R3,#0
 BNE ERTYPEARRAYC
MATRIXMULTIPLYMAIN CMP TYPE,#TFPLV
;at this instant r3,r7,r8,r9,r10,r11,r14 are free
;r4=base of dest; r1=base of left source; r0=base of right source
;r2=LIMI; r5=LIMJ; r6=LIMK
 BEQ MATRIXMULTIPLYFP
 STMFD SP!,{R0} ;matrix multiply for integers: save r source base
 MOV R6,R6,LSL #2 ;LIMK=LIMK*4
;main loop over i
MATRIXMULTIPLYINT1 LDMFD SP,{R0} ;reload r source base
 MOV R11,R6 ;loop count: LIMK*4
;outer loop over k
MATRIXMULTIPLYINT2 MOV R3,#0 ;result
 MOV R14,R1 ;l source
 MOV R7,R0 ;r source
 MOV R8,R5 ;loop count: LIMJ
;inner loop over j
MATRIXMULTIPLYINT3 LDR R9,[R14],#4 ;inner copy of l source
 LDR R10,[R7],R6 ;step inner copy of r source by LIMK*4
 MLA R3,R9,R10,R3
 SUBS R8,R8,#1
 BNE MATRIXMULTIPLYINT3
 STR R3,[R4],#4 ;step destination
 ADD R0,R0,#4 ;step outer r source
 SUBS R11,R11,#4
 BNE MATRIXMULTIPLYINT2
 ADD R1,R1,R5,LSL #2 ;step l source by LIMJ*4
 SUBS R2,R2,#1 ;decrement LIMI directly in main loop
 BNE MATRIXMULTIPLYINT1
 LDMFD SP!,{R0,R8,R10}
 B NXT
MATRIXMULTIPLYFP
 [ FP=0
 ADD R5,R5,R5,LSL #2 ;LIMJ'=LIMJ*5
 STMFD SP!,{R0,R1,R2,R4,R5}
 SUB SP,SP,#8
;SP+0 = r source base
;SP+4 = outer loop counter
;SP+8 = r source base (original)
;SP+12= l source base
;SP+16= LIMI
;SP+20= dest base
;SP+24= LIMJ*5
 ADD R11,R6,R6,LSL #2 ;LIMK'=LIMK*5
;main loop over i
MATRIXMULTIPLYFP1 LDR R0,[SP,#8] ;reload r source base
 STR R0,[SP]
 STR R11,[SP,#4] ;loop count: LIMK*5
;outer loop over k
MATRIXMULTIPLYFP2 BL FCLR ;result
 LDR R10,[SP,#12] ;l source
 LDR TYPE,[SP] ;r source
 LDR R8,[SP,#24] ;loop count: LIMJ*5
;inner loop over j
MATRIXMULTIPLYFP3 STMFD SP!,{R0-R3} ;save accumulated value
 MOV R4,TYPE
 MOV TYPE,R10
 ADD R10,R10,#5 ;step inner copy of l source
 BL F1LDA
 MOV TYPE,R4
 BL F1MUL
 ADD TYPE,TYPE,R11 ;step inner copy of r source by LIMK*5
 LDMFD SP!,{R4-R7}
 BL FADDW
 SUBS R8,R8,#5
 BNE MATRIXMULTIPLYFP3
 LDR TYPE,[SP,#20]
 BL F1STA
 ADD TYPE,TYPE,#5
 STR TYPE,[SP,#20] ;step destination
 LDR R0,[SP]
 ADD R0,R0,#5
 STR R0,[SP] ;step outer r source
 LDR R0,[SP,#4]
 SUBS R0,R0,#5
 STRNE R0,[SP,#4]
 BNE MATRIXMULTIPLYFP2
 LDR R0,[SP,#12]
 LDR R1,[SP,#24]
 ADD R0,R0,R1 ;step l source by LIMJ*5
 STR R0,[SP,#12]
 LDR R0,[SP,#16]
 SUBS R0,R0,#1
 STRNE R0,[SP,#16] ;decrement LIMI directly in main loop
 BNE MATRIXMULTIPLYFP1
 ADD SP,SP,#7*4
 |
 MOV R6,R6,LSL #3 ;LIMK=LIMK*8
;main loop over i
MATRIXMULTIPLYFP1 MOV R10,R0 ;reload r source base
 MOV R11,R6 ;loop count: LIMK*8
;outer loop over k
MATRIXMULTIPLYFP2 MVFD FACC,#0 ;result
 MOV R14,R1 ;l source
 MOV R7,R10 ;r source
 MOV R8,R5 ;loop count: LIMJ
;inner loop over j
MATRIXMULTIPLYFP3 LDFD F1,[R14],#8 ;inner copy of l source
 LDFD F2,[R7]
 MUFD F1,F1,F2
 ADD R7,R7,R6 ;step inner copy of r source by LIMK*8
 SUBS R8,R8,#1
 ADFD FACC,FACC,F1
 BNE MATRIXMULTIPLYFP3
 STFD FACC,[R4],#8 ;step destination
 ADD R10,R10,#8 ;step outer r source
 SUBS R11,R11,#8
 BNE MATRIXMULTIPLYFP2
 ADD R1,R1,R5,LSL #3 ;step l source by LIMJ*8
 SUBS R2,R2,#1 ;decrement LIMI directly in main loop
 BNE MATRIXMULTIPLYFP1
 ]
 LDMFD SP!,{R8,R10}
 B NXT
VECTORMULTIPLY ADD R4,R4,#4 ;skip number of elements
 CMP R7,#0
 BEQ VECTORROWMULTIPLY
 CMP R2,R3
 CMPEQ R5,R7
 LDR R6,[R1],#8
 CMPEQ R6,#0
 BNE ERTYPEARRAYC
 ADD R0,R0,#4
 MOV R6,#1 ;LIMK=1
 B MATRIXMULTIPLYMAIN
VECTORROWMULTIPLY CMP R2,R10
 CMPEQ R3,R5
 LDR R6,[R0],#8
 CMPEQ R6,#0
 BNE ERTYPEARRAYC
 ADD R1,R1,#4
 MOV R5,R3 ;move LIMJ
 MOV R6,R10 ;move LIMK
 MOV R2,#1 ;LIMI=1
 B MATRIXMULTIPLYMAIN
;and the functions
SUM STMFD SP!,{R14}
 LDRB R10,[AELINE],#1
 CMP R10,#TLEN
 BEQ SUMLEN
 BL READARRAYFACTOR1
 SUBS R1,TYPE,#256
 BCC ERARRY
 BL GETARRAYSIZE
 CMP R1,#TFPLV
 [ FP=0
 BL FCLR
 ]
 BEQ SUMFP
 BHI SUMSTRING
 [ FP=1
 MOV IACC,#0
 ]
SUMINT LDR R1,[TYPE],#4
 ADD IACC,IACC,R1
 SUBS R10,R10,#1
 BNE SUMINT
 B PSINSTK
 [ FP=0
SUMFP BL F1ADD
 ADD TYPE,TYPE,#5
 SUBS R10,R10,#1
 BNE SUMFP
 |
SUMFP MVFD FACC,#0
SUMFP1 LDFD F1,[TYPE],#8
 ADFD FACC,FACC,F1
 SUBS R10,R10,#1
 BNE SUMFP1
 ]
 B FSINSTK
SUMSTRING ADD CLEN,ARGP,#STRACC
 ADD R7,CLEN,#256
SUMSTRING1 LDRB R0,[TYPE,#4]
 TEQ R0,#0
 BEQ SUMSTRING3
 ADD R5,CLEN,R0
 CMP R5,R7
 BCS ERLONG
 LOAD R1,TYPE,R4,R5
SUMSTRING2 LDRB R3,[R1],#1
 STRB R3,[CLEN],#1
 SUBS R0,R0,#1
 BNE SUMSTRING2
SUMSTRING3 ADD TYPE,TYPE,#5
 SUBS R10,R10,#1
 BNE SUMSTRING1
 MOVS TYPE,#0
 LDMFD SP!,{PC}
SUMLEN BL READARRAYFACTOR
 CMP TYPE,#256+128
 BNE ERTYPESTRINGARRAY
 BL GETARRAYSIZE
 MOV IACC,#0
SUMLEN3 LDRB R1,[TYPE,#4]
 ADD TYPE,TYPE,#5
 ADD IACC,IACC,R1
 SUBS R10,R10,#1
 BNE SUMLEN3
 B PSINSTK
MODULUS STMFD SP!,{R14}
 BL READARRAYFACTOR
 SUBS R1,TYPE,#256
 BCC ERARRY
 BL GETARRAYSIZE
 CMP R1,#TFPLV
 [ FP=0
 BL FCLR
 ]
 BEQ MODULUSFP
 BHI ERTYPENUMARRAY
 [ FP=1
 MOV IACC,#0
 ]
MODULUSINT LDR R1,[TYPE],#4
 MUL R2,R1,R1
 ADD IACC,IACC,R2
 SUBS R10,R10,#1
 BNE MODULUSINT
 [ FP=0
 BL IFLT
 BL FSQRT
 |
 FLTD FACC,IACC
 SQTD FACC,FACC
 ]
 B FSINSTK
MODULUSFP
 [ FP=0
 STMFD SP!,{R0-R3}
 BL F1LDA
 BL FSQR
 LDMFD SP!,{R4-R7}
 BL FADDW
 ADD TYPE,TYPE,#5
 SUBS R10,R10,#1
 BNE MODULUSFP
 BL FSQRT
 |
 MVFD FACC,#0
MODULUSFP1 LDFD F1,[TYPE],#8
 MUFD F1,F1,F1
 SUBS R10,R10,#1
 ADFD FACC,FACC,F1
 BNE MODULUSFP1
 SQTD FACC,FACC
 ]
 B FSINSTK
;support
READARRAYFACTOR LDRB R10,[AELINE],#1
READARRAYFACTOR1 STMFD SP!,{R14}
 CMP R10,#"("
 BNE READARRAYFACTOR2
 BL LVBLNK
 BEQ ERARRY
 BL AESPAC
 CMP R10,#")"
 LDMEQFD SP!,{PC}
 B ERBRA
READARRAYFACTOR2 SUB AELINE,AELINE,#1
 BL LVBLNK
 LDMNEFD SP!,{PC}
 B ERARRY
GETARRAYSIZE LDR TYPE,[IACC]
 CMP TYPE,#16
 BCC ERARRZ
GETARRAYSIZE1 LDR R6,[TYPE],#4
 CMP R6,#0
 BNE GETARRAYSIZE1
 LDR R10,[TYPE],#4
 MOV PC,R14
 LNK Assembler
